from app.schemas.payment import WalletCreate, WalletUpdate, Wallet, RedPacketCreate, RedPacketUpdate, RedPacket, TransactionCreate, Transaction
from app.database.connection import get_database
from datetime import datetime
from bson import ObjectId

async def get_user_wallet(user_id: str) -> Wallet:
    """获取用户钱包"""
    db = get_database()
    try:
        wallet_doc = await db["wallets"].find_one({"user_id": ObjectId(user_id)})
        if wallet_doc:
            wallet_response = wallet_doc.copy()
            wallet_response["id"] = str(wallet_response["_id"])
            wallet_response["user_id"] = str(wallet_response["user_id"])
            return Wallet(**wallet_response)
        
        # 如果钱包不存在，创建一个新钱包
        new_wallet = WalletCreate(user_id=user_id, balance=0.0)
        return await create_wallet(new_wallet)
    except Exception:
        return None

async def create_wallet(wallet: WalletCreate) -> Wallet:
    """创建钱包"""
    db = get_database()
    
    # 创建钱包文档
    wallet_dict = wallet.dict()
    wallet_dict["user_id"] = ObjectId(wallet_dict["user_id"])
    wallet_dict["created_at"] = datetime.utcnow()
    wallet_dict["updated_at"] = datetime.utcnow()
    
    # 插入数据库
    result = await db["wallets"].insert_one(wallet_dict)
    
    # 获取创建的钱包
    created_wallet = await db["wallets"].find_one({"_id": result.inserted_id})
    
    # 转换为Wallet对象
    wallet_response = created_wallet.copy()
    wallet_response["id"] = str(wallet_response["_id"])
    wallet_response["user_id"] = str(wallet_response["user_id"])
    
    return Wallet(**wallet_response)

async def update_wallet(user_id: str, wallet_update: WalletUpdate) -> Wallet:
    """更新钱包"""
    db = get_database()
    
    # 构建更新字典
    update_data = {k: v for k, v in wallet_update.dict().items() if v is not None}
    if not update_data:
        return await get_user_wallet(user_id)
    
    update_data["updated_at"] = datetime.utcnow()
    
    # 更新数据库
    result = await db["wallets"].update_one(
        {"user_id": ObjectId(user_id)},
        {"$set": update_data}
    )
    
    if result.modified_count == 0:
        return None
    
    return await get_user_wallet(user_id)

async def create_red_packet(red_packet: RedPacketCreate) -> RedPacket:
    """创建红包"""
    db = get_database()
    
    # 创建红包文档
    red_packet_dict = red_packet.dict()
    red_packet_dict["sender_id"] = ObjectId(red_packet_dict["sender_id"])
    red_packet_dict["receiver_id"] = ObjectId(red_packet_dict["receiver_id"])
    red_packet_dict["created_at"] = datetime.utcnow()
    if "claimed_at" in red_packet_dict and red_packet_dict["claimed_at"]:
        red_packet_dict["claimed_at"] = datetime.fromisoformat(red_packet_dict["claimed_at"])
    
    # 插入数据库
    result = await db["red_packets"].insert_one(red_packet_dict)
    
    # 获取创建的红包
    created_red_packet = await db["red_packets"].find_one({"_id": result.inserted_id})
    
    # 转换为RedPacket对象
    red_packet_response = created_red_packet.copy()
    red_packet_response["id"] = str(red_packet_response["_id"])
    red_packet_response["sender_id"] = str(red_packet_response["sender_id"])
    red_packet_response["receiver_id"] = str(red_packet_response["receiver_id"])
    
    return RedPacket(**red_packet_response)

async def update_red_packet(red_packet_id: str, red_packet_update: RedPacketUpdate) -> RedPacket:
    """更新红包"""
    db = get_database()
    
    # 构建更新字典
    update_data = {k: v for k, v in red_packet_update.dict().items() if v is not None}
    if "claimed_at" in update_data and update_data["claimed_at"]:
        update_data["claimed_at"] = datetime.fromisoformat(update_data["claimed_at"])
    
    if not update_data:
        return await get_red_packet(red_packet_id)
    
    # 更新数据库
    result = await db["red_packets"].update_one(
        {"_id": ObjectId(red_packet_id)},
        {"$set": update_data}
    )
    
    if result.modified_count == 0:
        return None
    
    return await get_red_packet(red_packet_id)

async def get_red_packet(red_packet_id: str) -> RedPacket:
    """获取红包详情"""
    db = get_database()
    try:
        red_packet_doc = await db["red_packets"].find_one({"_id": ObjectId(red_packet_id)})
        if red_packet_doc:
            red_packet_response = red_packet_doc.copy()
            red_packet_response["id"] = str(red_packet_response["_id"])
            red_packet_response["sender_id"] = str(red_packet_response["sender_id"])
            red_packet_response["receiver_id"] = str(red_packet_response["receiver_id"])
            return RedPacket(**red_packet_response)
        return None
    except Exception:
        return None

async def create_transaction(transaction: TransactionCreate) -> Transaction:
    """创建交易记录"""
    db = get_database()
    
    # 创建交易文档
    transaction_dict = transaction.dict()
    transaction_dict["user_id"] = ObjectId(transaction_dict["user_id"])
    if "related_id" in transaction_dict and transaction_dict["related_id"]:
        transaction_dict["related_id"] = ObjectId(transaction_dict["related_id"])
    transaction_dict["created_at"] = datetime.utcnow()
    
    # 插入数据库
    result = await db["transactions"].insert_one(transaction_dict)
    
    # 获取创建的交易记录
    created_transaction = await db["transactions"].find_one({"_id": result.inserted_id})
    
    # 转换为Transaction对象
    transaction_response = created_transaction.copy()
    transaction_response["id"] = str(transaction_response["_id"])
    transaction_response["user_id"] = str(transaction_response["user_id"])
    if transaction_response["related_id"]:
        transaction_response["related_id"] = str(transaction_response["related_id"])
    
    return Transaction(**transaction_response)

async def get_user_transactions(user_id: str, skip: int = 0, limit: int = 100) -> list[Transaction]:
    """获取用户交易记录"""
    db = get_database()
    transactions_cursor = db["transactions"].find({"user_id": ObjectId(user_id)}).skip(skip).limit(limit)
    transactions = await transactions_cursor.to_list(length=limit)
    
    result = []
    for transaction_doc in transactions:
        transaction_response = transaction_doc.copy()
        transaction_response["id"] = str(transaction_response["_id"])
        transaction_response["user_id"] = str(transaction_response["user_id"])
        if transaction_response["related_id"]:
            transaction_response["related_id"] = str(transaction_response["related_id"])
        result.append(Transaction(**transaction_response))
    
    return result